#ifdef BACK_POINT_SUPPORT
#ifndef BSUPPORT_CPP 
#define BSUPPORT_CPP 1

#include "csp_base.h"
#include "bsupport.h"
#include <iostream>

using namespace std;


BackSupportList::~BackSupportList()
{
	//cout << "Destructor: BackSupportList Begin" << endl;
	if(nlist!=NULL) delete [] nlist;
	//cout << "Destructor: BackSupportList End" << endl;
}

void BackSupportList::deleteNode(BackSupportNode* node)
{
	//cout << "Deleting node: " << (void*)node << endl;
	node->next=nextEmpty->next;
	if(nextEmpty->next!=NULL)
		nextEmpty->next->pre=node;
	nextEmpty->next=node;
	node->pre=nextEmpty;
	//cout << " Done." << endl;

	//count--;
	//cout << "removeSupport removed:" << count<< endl;
}

void BackSupportList::generateList(int numvar, int domsize,int edges)
{
	//cout << "Generating list" << endl;
	listcount=edges*domsize*2+1;
	nlist= new BackSupportNode[listcount];
	//if(lists==NULL)
	//{
		//cout << "Failure! Not enough memory for support list!" << endl;
	//	exit(1);
	//}
	nextEmpty=nlist;
	
	BackSupportNode* sp=nlist;
	sp->pre=NULL;
	for(int i=0;i<listcount-1;i++)
	{
		sp->value=0;
		sp->dependants=0;
		sp->next=sp+1;
		sp++;
		sp->pre=sp-1;
	}
	sp->value=0;
	sp->dependants=0;
	sp->next=NULL;

	//cout << "Generated super support list" << endl;
}

void BackSupportList::removeSupport(Domain * var,BackSupportNode* val)
{
	//cout << "Removing Support: ";
	(val->dependants)--;
	if(val->dependants>0)
	{
		//cout << "More than this dependant, nothing performed." << endl;
		return;
	}
	if(val->pre!=NULL)
	{
		//cout << "Previous supports... ";
		BackSupportNode* prev=val->pre;
		prev->next=val->next;
		if(val->next!=NULL)
		{
			//cout << "Next supports... Done" << endl;
			val->next->pre=prev;
		}
		else
		{
			//cout << "No next supports. Done" << endl;
		}
	}
	else if(val->next!=NULL)
	{
		//cout << "Next Supports... Done" << endl;
		var[val->value].supported=val->next;
		val->next->pre=NULL;
	}
	else
	{
		//cout << "Only Dependant, removing node" << endl;
		var[val->value].supported=NULL;
	}
	deleteNode(val);
}


BackSupportNode* BackSupportList::setSupport(Domain* var,int val)
{
	BackSupportNode* retval=var[val].supported;
	if(retval==NULL)
	{
		retval=nextEmpty;
		nextEmpty=retval->next;
		retval->value=val;
		retval->next=NULL;
		retval->pre=NULL;
		var[val].supported=retval;
	}
	(retval->dependants)++;
	return retval;
}

void BackSupportList::transferSupport(Domain* var,BackSupportNode* val1,int val2)
{
	if(val1==NULL)
	{
		//cout << "deleted value has no supports" << endl;
		return;
	}
	val1->value=val2;
	BackSupportNode* beyond=val1;
	while(beyond->next!=NULL)
	{
		beyond=beyond->next;
		//cout << "supports being set: " << (void*)beyond << endl;
		//getchar();
		beyond->value=val2;
	}
	if(var[val2].supported==NULL)
	{
		//cout << "transfered value " << val2 << " has no supports" << endl;
		var[val2].supported=val1;
		return;
	}
	//cout << "Adding deleted supports to remaining value " << val2 << ": ";
	BackSupportNode* trans=var[val2].supported;
    trans->pre=beyond;
	beyond->next=trans;
	var[val2].supported=val1;
	//cout << "supports transferred" << endl;
}

#endif
#endif
